package aggregate.aggregator;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.List;

import aggregate.aggregator.remote.AggregatorRemoteInterface;
import aggregate.aggregator.remote.Category;
import aggregate.aggregator.remote.Client;
import aggregate.aggregator.remote.Comment;


/**
 * @author andreivajnaii
 * The Aggregator service to which the Client applications connect to
 */
public class Aggregator implements AggregatorRemoteInterface {
	
	private Database database;
	
	public Aggregator(Database db) {
		database = db;
	}
	
	@Override
	public List<Category> getCategories() {
		Connection con = database.connect();
		List<Category> categories = database.getCategories(con);
		try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return categories;
	}

	@Override
	public void subscribe(String hostname, int categoryId) throws RemoteException {
		Connection con = database.connect();
		database.subscribeClient(con, hostname, categoryId);
		try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void addRating(int contentId, double value) {
		Connection con = database.connect();
		database.insertRatingForContent(con, contentId, value);
		notifyRating(con, contentId, value);
		try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void addComment(int contentId, Comment comment) {
		
		comment.setCreated(new Timestamp(System.currentTimeMillis()));
		comment.setContentId(contentId);
		Connection con = database.connect();
		database.insertComment(con, comment);
		notifyComment(con, comment);
		try {
			con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	void notifyRating(Connection con, int contentId, double value) {
		int categoryId = database.getCategoryIdForContentId(con, contentId);
		List<Client> clients = database.getClientsForCategory(con, categoryId);
		for (Client client : clients) {
			try {
				client.notifyRating(contentId, value);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}
	
	void notifyComment(Connection con, Comment comment) {
		int categoryId = database.getCategoryIdForContentId(con, comment.getContentId());
		List<Client> clients = database.getClientsForCategory(con, categoryId);
		for (Client client : clients) {
			try {
				client.notifyComment(comment);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void verifyUpdates()
	{
		Connection con = null;
		try	{
			con = database.connect();
			List<Category> categories = database.getCategories(con);
			Iterator<Category> iterator = categories.iterator(); 
			while(iterator.hasNext())
			{
				Category category = (Category) iterator.next();
				List<Feed> feeds = database.getFeedsForCategory(con, category.getId());
				List<Client> clients = database.getClientsForCategory(con, category.getId());
				new Channel(category).verifyUpdates(con, database, feeds, clients);
			}
			con.close();
		} catch(SQLException e)	{
			System.out.println(e.getMessage());
			e.printStackTrace();
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
